using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using ZuDoKu.Utilities;

namespace ZuDoKu.Controls
{
    public enum ButtonSelectionState
    {
        Normal,
        Selected
    }

    public enum ButtonPressStyle
    {
        Press,
        Release
    }

    public class Button : Control
    {
        private const int DefaultHeight = 25;
        private const int DefaultWidth = 100;

        Label _text = new Label();

        public string Text
        {
            get { return _text.Text; }
            set 
            {
                _text.Text = value;
                CalculateTextOffset();
            }
        }

        public override int Width
        {
            get { return base.Width; }
            set
            {
                base.Width = value;
                CalculateTextOffset();
            }
        }

        public override int Height
        {
            get { return base.Height; }
            set
            {
                base.Height = value;
                CalculateTextOffset();
            }
        }

        public ButtonSelectionState SelectionState
        {
            get { return (ButtonSelectionState)State; }
            set 
            { 
                State = (int)value;
            }
        }

        public ButtonPressStyle PressStyle { get; set; }

        public Button(Texture2D texture)
            : base(texture, DefaultWidth, DefaultHeight, 1, 2)
        {
            PressStyle = ButtonPressStyle.Press;
            IsContainer = true;
            Controls.Add(_text);
        }

        ButtonState _lastState = ButtonState.Released;

        protected override void ProcessInput(GamePadState state)
        {
            Vector2 stick = state.ThumbSticks.Left;
            bool pressed = false;

            if ((stick.X != 0 || stick.Y != 0))
            {
                pressed = (PressStyle == ButtonPressStyle.Press &&
                _lastState == ButtonState.Released &&
                (state.IsButtonDown(Buttons.DPadDown) ||
                state.IsButtonDown(Buttons.DPadLeft) || 
                state.IsButtonDown(Buttons.DPadRight) || 
                state.IsButtonDown(Buttons.DPadUp)) ||
                (PressStyle == ButtonPressStyle.Release &&
                _lastState == ButtonState.Pressed &&
                (state.IsButtonUp(Buttons.DPadDown) ||
                state.IsButtonUp(Buttons.DPadLeft) ||
                state.IsButtonUp(Buttons.DPadRight) ||
                state.IsButtonUp(Buttons.DPadUp))));

                _lastState = (state.IsButtonDown(Buttons.DPadDown) ||
                    state.IsButtonDown(Buttons.DPadLeft) ||
                    state.IsButtonDown(Buttons.DPadRight) ||
                    state.IsButtonDown(Buttons.DPadUp)) ? 
                    ButtonState.Pressed : 
                    ButtonState.Released;
            }
            else 
            {
                pressed =(PressStyle == ButtonPressStyle.Press &&
                _lastState == ButtonState.Released &&
                state.IsButtonDown(Buttons.A)) ||
                PressStyle == ButtonPressStyle.Release &&
                _lastState == ButtonState.Pressed &&
                state.IsButtonUp(Buttons.A);
             
                _lastState = state.Buttons.A;
            }

            if(pressed)
                OnPressed();
        }

        public event EventHandler Pressed;
        protected virtual void OnPressed()
        {
            if (Pressed != null) 
                Pressed(this, EventArgs.Empty);
        }
        
        private void CalculateTextOffset()
        {
            _text.X = (Width / 2) - _text.Width / 2;
            _text.Y = (Height / 2) - _text.Height / 2;
        }

        public override string ToString()
        {
            return _text.ToString();
        }
    }
}
